//============================================================================
// Name        : decorator_pattern.cpp
// Author      : Tony
// Version     :
// Copyright   : GPLv2
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
using namespace std;

class Widget
{
public:
	Widget()
	{
		cout<<"construct Widget"<<endl;
	}
	virtual ~Widget()
	{
		cout<<"destroy Widget"<<endl;
	}
	virtual void draw()
	{
		cout<<"draw widget"<<endl;
	}
};
class TextField : public Widget
{
public:
	TextField()
	{
		cout<<"construct TextField"<<endl;
	}
	virtual ~TextField()
	{
		cout<<"destroy TextField"<<endl;
	}
	void draw()
	{
		cout<<"draw TextField"<<endl;
	}
};

class Decorator : public Widget
{
public:
	Decorator(Widget* widget)
	{
		cout<<"construct Decorator"<<endl;
		wrappee = widget;
	}
	virtual ~Decorator()
	{
		delete wrappee;
		cout<<"destroy Decorator"<<endl;
	}

	void draw()
	{
		wrappee->draw();
	}
protected:
	Widget* wrappee;
};

class ScrollDecorator : public Decorator
{
public:
	ScrollDecorator(Widget* widget) : Decorator(widget)
	{
		cout<<"construct ScrollDecorator"<<endl;
	}
	virtual ~ScrollDecorator()
	{
		cout<<"destroy ScrollDecorator"<<endl;
	}

	void draw()
	{
		wrappee->draw();
		cout<<"ScrollDecorator draw"<<endl;
	}
};

class BorderDecorator : public Decorator
{
public:
	BorderDecorator(Widget* widget) : Decorator(widget)
	{
		cout<<"construct BorderDecorator"<<endl;
	}

	virtual ~BorderDecorator()
	{
		cout<<"destroy BorderDecorator"<<endl;
	}

	void draw()
	{
		wrappee->draw();
		cout<<"BorderDecorator draw"<<endl;
	}
};

int main() {
	Widget* widget = new BorderDecorator(new ScrollDecorator(new TextField()));
	cout<<"================="<<endl;
	widget->draw();
	cout<<"================="<<endl;
	delete widget;
	return 0;
}
